package main

import (
	"database/sql"
	"fmt"
	_ "github.com/denisenkom/go-mssqldb" // 指定别名为_
	"html/template"
	"log"
	"mymath"
	"net/http"
	"reflect"
	"strings"
)

/**
 * @brief: 测试方位MSSql
 * @desc:
 *
 */
func testGetDataFromMSSql() {
	connStr := fmt.Sprintf("server=%s;database=%s;user id=%s;password=%s;port=%d;encrypt=disable", "192.168.16.23", "QPAccountsDB", "sa", "sa", 1433)
	db, err := sql.Open("mssql", connStr)
	if err != nil {
		log.Fatal("testGetDataFromMSSql-1:", err)
		return
	}

	stmt, err := db.Prepare("select UserId, Accounts, NickName from AccountsInfo where Accounts like(?)")
	if err != nil {
		log.Fatal("testGetDataFromMSSql-2:", err)
		return
	}

	err = db.Ping()
	if err != nil {
		log.Fatal("testGetDataFromMSSql-3:", err)
		return
	}

	sqlCmdPara := "%enic%"
	fmt.Println("sqlCmdPara=%s", sqlCmdPara)
	rows, err := stmt.Query(sqlCmdPara) // 注意Query  Exec区别
	if err != nil {
		log.Fatal("testGetDataFromMSSql-4:", err)
		return
	}

	defer stmt.Close()

	fmt.Println("db: get data\n")
	fmt.Println("db: show the query result")

	// 显示查询返回的字段
	scan_result_key, _ := rows.Columns()
	for index := range scan_result_key {
		fmt.Println(scan_result_key[index])
		fmt.Println("\n")
	}

	scan_result_value := make([]interface{}, len(scan_result_key))

	for index, _ := range scan_result_key {
		scan_result_value[index] = new(sql.RawBytes)
	}

	// 定义一个变长数组存放全部行
	var record_set []map[string]sql.RawBytes

	rowNumber := 0
	for rows.Next() {
		err := rows.Scan(scan_result_value...)
		if err != nil {
			log.Fatal(err)
		}

		// 存放一行结果集
		record_row := make(map[string]sql.RawBytes)

		// 保存当前行的每一个字段
		for index := range scan_result_value {
			value := scan_result_value[index].(*sql.RawBytes)
			record_row[scan_result_key[index]] = *value
			fmt.Println(reflect.TypeOf(value))
		}

		// 保存当前行
		record_set = append(record_set, record_row)

		rowNumber = rowNumber + 1
	}

	// 读取第二行的第二个字段
	val := string(record_set[1]["Accounts"])

	fmt.Println("Accounts=%s", val)

	/* 老老实实通过scan匹配好字段的方式获取返回数据
	for rows.Next() {
		//var value int
		// if ers := rows.Scan(&value); ers == nil {
		//     fmt.Println(value)
		// }

		var userId int
		var account string
		err := rows.Scan(&userId, &account) // 值必须和输出匹配
		if err != nil {
			log.Fatal("testGetDataFromMSSql-5:", err)
			return
		}

		fmt.Println("%d,%s", userId, account)
	}
	*/
}

/**
 * @desc:
 * 尝试用http://192.168.16.186:99/?a=1&b=2访问，观察输出
 * 注意每个连接是在独立的goroutine里边
 */
func sayHelloName(w http.ResponseWriter, r *http.Request) {
	r.ParseForm() // 解析参数，默认是不解析
	//fmt.Println(r.Form)
	//fmt.Println("path", r.URL.Path)
	//fmt.Println("scheme", r.URL.Scheme)
	//fmt.Println(r.Form["url_long"])
	for k, v := range r.Form {
		fmt.Println("key:", k)
		fmt.Println("val:", strings.Join(v, ""))
	}

	fmt.Fprintf(w, "Hello GoWeb") // 写到浏览器上的
}

/*
func test_sayHelloName() {
    http.HandleFunc("/", sayHelloName)   // 设置路由
    err := http.ListenAndServe(":99", nil)         // 设置监听端口

    if err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}
*/

func logonForm(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	fmt.Println("method:", r.Method) // 获取请求的方法
	if r.Method == "GET" {
		t, _ := template.ParseFiles("login.gtpl")
		t.Execute(w, nil)
	} else { // 请求的是登陆数据，执行登陆逻辑判定
		// 获取参数
		userName := r.Form["user_name"]
		password := r.Form["password"]

		// 服务器控制台输出
		fmt.Println("user_name:", userName)
		fmt.Println("password:", password)

		// 客户端浏览器输出
		template.HTMLEscape(w, []byte(r.Form.Get("user_name")))

	}
}

func startHttpService() {
	// 安装路由
	http.HandleFunc("/", sayHelloName)
	http.HandleFunc("/login", logonForm)

	err := http.ListenAndServe(":99", nil) // 设置监听端口

	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}

func main() {
	fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2))

	fmt.Printf("start\n")
	testGetDataFromMSSql()
	//test_sayHelloName()
	startHttpService()

}
